﻿// (c) Copyright Fernando Cerqueira.
// This source is subject to the Microsoft Public License (Ms-PL).
// Please see http://go.microsoft.com/fwlink/?LinkID=131993 for details.
// All other rights reserved.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;

// ReSharper disable CheckNamespace
namespace DevPhone.Controls
// ReSharper restore CheckNamespace
{
    public class WindowsBoxService : 
        IWindowsBoxService, // custom messages
        IWindowsBoxSettingsService, //settings global properties for servive
        IWindowsBoxMessage, // standard messagebox (inf/error/warning/question)
        IWindowsBoxDateTimePicker, //datetimepicker common
        IWindowsBoxDatePicker, //datepicker
        IWindowsBoxTimePicker //timepicker
    {

        #region internal constructor

        internal WindowsBoxService()
        {
        }

        #endregion

        #region Public static methods

        public static void ResetToDefaultValues()
        {
            _borderColor = (Color)Application.Current.Resources["PhoneForegroundColor"];
            _cornerRadius = 8;
            _border = 2;
            _overlayOpacity = 0.5;
            _overlayColor = (Color)Application.Current.Resources["PhoneChromeColor"];

            DefaultBorderBrush = new SolidColorBrush(_borderColor);
            DefaultOverlayBrush = new SolidColorBrush(_overlayColor) { Opacity = _overlayOpacity };
            DefaultOverlayBrush = new SolidColorBrush(_overlayColor) { Opacity = _overlayOpacity };
            DefaultThicknessTitle = new Thickness(_border, _border, _border, _border);
            DefaultThicknessMessage = new Thickness(_border, 0, _border, 0);
            DefaultThicknessButtons = new Thickness(_border, 0, _border, _border);
            DefaultCornerRadiusTop = new CornerRadius(_cornerRadius, _cornerRadius, 0, 0);
            DefaultCornerRadiusBottom = new CornerRadius(0, 0, _cornerRadius, _cornerRadius);


            DefaultErrorBackgroundBrush = new SolidColorBrush(Colors.Red);
            DefaultErrorForegroundBrush = new SolidColorBrush(Colors.White);
            DefaultWarningBackgroundBrush = new SolidColorBrush(Colors.Yellow);
            DefaultWarningForegroundBrush = new SolidColorBrush(Colors.Black);
            DefaultInformationBackgroundBrush = new SolidColorBrush(Colors.Blue);
            DefaultInformationForegroundBrush = new SolidColorBrush(Colors.White);
            DefaultQuestionBackgroundBrush = new SolidColorBrush(Colors.Green);
            DefaultQuestionForegroundBrush = new SolidColorBrush(Colors.White);
            DefaultTitleBackgroundBrush = (Brush)Application.Current.Resources["PhoneAccentBrush"];
            DefaultTitleForegroundBrush = (Brush)Application.Current.Resources["PhoneForegroundBrush"];
            DefaultContentBackgroundBrush = (Brush)Application.Current.Resources["PhoneChromeBrush"];
            DefaultContentForegroundBrush = (Brush)Application.Current.Resources["PhoneForegroundBrush"];
            DefaultButtonBackgroundBrush = new SolidColorBrush(Colors.Transparent);
            DefaultButtonForegroundBrush = (Brush)Application.Current.Resources["PhoneForegroundBrush"];
        }
        public static IWindowsBoxSettingsService Settings()
        {
            return new WindowsBoxService();
        }

        public static IWindowsBoxService Set()
        {
            if (IsOpen)
            {
                throw new InvalidOperationException("Message Service already running.");
            }
            _windowsBoxBaseRef = new WindowsBox
            {
                TypeMessage = WindowsBoxTypeMessage.UserType,
                ShowIconType = WindowsBoxIconType.None
            };
            return new WindowsBoxService();
        }
        public static IWindowsBoxMessage Box()
        {
            if (IsOpen)
            {
                throw new InvalidOperationException("Message Service already running.");
            }
            _windowsBoxBaseRef = new WindowsBox
            {
                TypeMessage = WindowsBoxTypeMessage.InformationType,
                ShowIconType = WindowsBoxIconType.Information
            };
            return new WindowsBoxService();
        }
        public static IWindowsBoxDateTimePicker DateTimePicker()
        {
            if (IsOpen)
            {
                throw new InvalidOperationException("Message Service already running.");
            }
            _windowsBoxBaseRef = new WindowsBox
            {
                TypeMessage = WindowsBoxTypeMessage.UserType,
                ShowIconType = WindowsBoxIconType.None
            };
            return new WindowsBoxService();
        }

        public static void Close()
        {
            if (_windowsBoxBaseRef == null)
            {
                throw new InvalidOperationException("Message Service not created.");
            }
            if (!IsOpen)
            {
                throw new InvalidOperationException("Message Service not opened.");
            }
            switch (_windowsBoxBaseRef.TypeMessage)
            {
                case WindowsBoxTypeMessage.UserType:
                case WindowsBoxTypeMessage.ErrorType:
                case WindowsBoxTypeMessage.WarningType:
                case WindowsBoxTypeMessage.InformationType:
                case WindowsBoxTypeMessage.QuestionType:
                    ((WindowsBox)_currentWindowsShow).Close();
                    break;
                case WindowsBoxTypeMessage.DatePicker:
                    ((WindowsBoxDatePicker)_currentWindowsShow).Close();
                    break;
                case WindowsBoxTypeMessage.TimePicker:
                    ((WindowsBoxTimePicker)_currentWindowsShow).Close();
                    break;
                default:
                    throw new InvalidOperationException("Invalid type message for method : " + _windowsBoxBaseRef.TypeMessage);
            }
            CleanUp();
        }
        public static void Close(int value)
        {
            if (_windowsBoxBaseRef == null)
            {
                throw new InvalidOperationException("Message Service not created.");
            }
            if (!IsOpen)
            {
                throw new InvalidOperationException("Message Service not opened.");
            }
            if (_windowsBoxBaseRef.ButtonType != WindowsBoxButtonType.Custom)
            {
                throw new InvalidOperationException("Message Service not Button Type Custom.");
            }
            switch (_windowsBoxBaseRef.TypeMessage)
            {
                case WindowsBoxTypeMessage.UserType:
                case WindowsBoxTypeMessage.ErrorType:
                case WindowsBoxTypeMessage.WarningType:
                case WindowsBoxTypeMessage.InformationType:
                case WindowsBoxTypeMessage.QuestionType:
                    ((WindowsBox)_currentWindowsShow).Close(value);
                    break;
                default:
                    throw new InvalidOperationException("Invalid type message for method : " + _windowsBoxBaseRef.TypeMessage);
            }
            CleanUp();
        }
        public static void Close(WindowsBoxButtonResult buttonResult)
        {
            if (_windowsBoxBaseRef == null)
            {
                throw new InvalidOperationException("Message Service not created.");
            }
            if (!IsOpen)
            {
                throw new InvalidOperationException("Message Service not opened.");
            }
            if (_windowsBoxBaseRef.ButtonType == WindowsBoxButtonType.Custom)
            {
                throw new InvalidOperationException("Message Service is Button Type Custom.");
            }
            switch (_windowsBoxBaseRef.TypeMessage)
            {
                case WindowsBoxTypeMessage.UserType:
                case WindowsBoxTypeMessage.ErrorType:
                case WindowsBoxTypeMessage.WarningType:
                case WindowsBoxTypeMessage.InformationType:
                case WindowsBoxTypeMessage.QuestionType:
                    ((WindowsBox)_currentWindowsShow).Close(buttonResult);
                    break;
                case WindowsBoxTypeMessage.DatePicker:
                    ((WindowsBoxDatePicker)_currentWindowsShow).Close(buttonResult);
                    break;
                case WindowsBoxTypeMessage.TimePicker:
                    ((WindowsBoxTimePicker)_currentWindowsShow).Close(buttonResult);
                    break;
                default:
                    throw new InvalidOperationException("Invalid type message for method : " + _windowsBoxBaseRef.TypeMessage);
            }
            CleanUp();
        }

        #endregion

        #region public static Properties

        public static bool IsOpen { get; internal set; }

        #endregion

        #region private static fields

        private static UIElement _currentWindowsShow;
        private static WindowsBoxBase _windowsBoxBaseRef;

        private static double _cornerRadius = 8;
        private static double _border = 2;
        private static double _overlayOpacity = 0.5;
        private static Color _overlayColor = DesignerProperties.IsInDesignTool ? Colors.Transparent : (Color)Application.Current.Resources["PhoneChromeColor"];
        private static Color _borderColor = DesignerProperties.IsInDesignTool ? Colors.Transparent : (Color)Application.Current.Resources["PhoneForegroundColor"];
        //private static readonly UIElement RootVisual = Application.Current == null ? null : Application.Current.RootVisual;

        #endregion

        #region internal static fields

        internal static Brush DefaultOverlayBrush = DesignerProperties.IsInDesignTool ? null : new SolidColorBrush(_overlayColor) { Opacity = _overlayOpacity };
        internal static CornerRadius DefaultCornerRadiusTop = new CornerRadius(_cornerRadius, _cornerRadius, 0, 0);
        internal static CornerRadius DefaultCornerRadiusBottom = new CornerRadius(0, 0, _cornerRadius, _cornerRadius);
        internal static Thickness DefaultThicknessTitle = new Thickness(_border, _border, _border, _border);
        internal static Thickness DefaultThicknessMessage = new Thickness(_border, 0, _border, 0);
        internal static Thickness DefaultThicknessButtons = new Thickness(_border, 0, _border, _border);
        internal static Brush DefaultBorderBrush = DesignerProperties.IsInDesignTool ? null : (Brush)Application.Current.Resources["PhoneForegroundBrush"];
        internal static Brush DefaultErrorBackgroundBrush = new SolidColorBrush(Colors.Red);
        internal static Brush DefaultErrorForegroundBrush = new SolidColorBrush(Colors.White);
        internal static Brush DefaultWarningBackgroundBrush = new SolidColorBrush(Colors.Yellow);
        internal static Brush DefaultWarningForegroundBrush = new SolidColorBrush(Colors.Black);
        internal static Brush DefaultInformationBackgroundBrush = new SolidColorBrush(Colors.Blue);
        internal static Brush DefaultInformationForegroundBrush = new SolidColorBrush(Colors.White);
        internal static Brush DefaultQuestionBackgroundBrush = new SolidColorBrush(Colors.Green);
        internal static Brush DefaultQuestionForegroundBrush = new SolidColorBrush(Colors.White);
        internal static Brush DefaultTitleBackgroundBrush = DesignerProperties.IsInDesignTool ? null : (Brush)Application.Current.Resources["PhoneAccentBrush"];
        internal static Brush DefaultTitleForegroundBrush = DesignerProperties.IsInDesignTool ? new SolidColorBrush(Colors.White) : (Brush)Application.Current.Resources["PhoneForegroundBrush"];
        internal static Brush DefaultContentBackgroundBrush = DesignerProperties.IsInDesignTool ? null : (Brush)Application.Current.Resources["PhoneChromeBrush"];
        internal static Brush DefaultContentForegroundBrush = DesignerProperties.IsInDesignTool ? null : (Brush)Application.Current.Resources["PhoneForegroundBrush"];
        internal static Brush DefaultButtonBackgroundBrush = new SolidColorBrush(Colors.Transparent);
        internal static Brush DefaultButtonForegroundBrush = DesignerProperties.IsInDesignTool ? null : (Brush)Application.Current.Resources["PhoneForegroundBrush"];


        #endregion

        #region private static methods

        private static void InternalShow(IList<object> args)
        {
            if (args == null)
            {
                throw  new ArgumentNullException("args");
            }
            IsOpen = true;
            if (_windowsBoxBaseRef != null)
            {
                switch (_windowsBoxBaseRef.TypeMessage)
                {
                    case WindowsBoxTypeMessage.UserType:
                    case WindowsBoxTypeMessage.ErrorType:
                    case WindowsBoxTypeMessage.WarningType:
                    case WindowsBoxTypeMessage.InformationType:
                    case WindowsBoxTypeMessage.QuestionType:
                        _currentWindowsShow = new WindowsBox
                        {
                            Title = _windowsBoxBaseRef.Title,
                            ActionClosed = _windowsBoxBaseRef.ActionClosed,
                            ActionOpen = _windowsBoxBaseRef.ActionOpen,
                            Buttons = _windowsBoxBaseRef.Buttons,
                            ButtonType = _windowsBoxBaseRef.ButtonType,
                            TypeMessage = _windowsBoxBaseRef.TypeMessage,
                            ShowIconType = _windowsBoxBaseRef.ShowIconType,
                            ExternalIcon = _windowsBoxBaseRef.ExternalIcon,
                            MessageContent = args[0],
                        };
                        break;
                    case WindowsBoxTypeMessage.DatePicker:
                        _currentWindowsShow = new WindowsBoxDatePicker
                        {
                            Title = _windowsBoxBaseRef.Title,
                            ActionClosed = _windowsBoxBaseRef.ActionClosed,
                            ActionOpen = _windowsBoxBaseRef.ActionOpen,
                            Buttons = _windowsBoxBaseRef.Buttons,
                            ButtonType = _windowsBoxBaseRef.ButtonType,
                            ShowIconType = WindowsBoxIconType.None,
                            TypeMessage = _windowsBoxBaseRef.TypeMessage,
                            ExternalIcon = null,
                            DateTimeSelected = (DateTime?)args[0],
                            ShowPart = (WindowsBoxDatePickerShowPart)args[1]
                        };
                        break;
                    case WindowsBoxTypeMessage.TimePicker:
                        _currentWindowsShow = new WindowsBoxTimePicker
                        {
                            Title = _windowsBoxBaseRef.Title,
                            ActionClosed = _windowsBoxBaseRef.ActionClosed,
                            ActionOpen = _windowsBoxBaseRef.ActionOpen,
                            Buttons = _windowsBoxBaseRef.Buttons,
                            ButtonType = _windowsBoxBaseRef.ButtonType,
                            ShowIconType = WindowsBoxIconType.None,
                            TypeMessage = _windowsBoxBaseRef.TypeMessage,
                            ExternalIcon = null,
                            DateTimeSelected = (DateTime?)args[0]
                        };
                        break;
                    default:
                        throw new InvalidOperationException("Invalid type message for method : " + _windowsBoxBaseRef.TypeMessage);
                }
                _windowsBoxBaseRef.IsOpen = true;
                _windowsBoxBaseRef.RootGridHost.Children.Add(_currentWindowsShow);
            }
        }

        private static void EnsureState()
        {
            if (IsOpen)
            {
                throw new InvalidOperationException("Message Service already opened.");
            }
        }

        private static IWindowsBoxService Create(WindowsBoxTypeMessage type)
        {
            if (IsOpen)
            {
                throw new InvalidOperationException("Message Service already running.");
            }
            _windowsBoxBaseRef = new WindowsBox
            {
                TypeMessage = type,
                ShowIconType = WindowsBoxIconType.None
            };
            return new WindowsBoxService();
        }

        private static void CleanUp()
        {
            IsOpen = false;
            _windowsBoxBaseRef = null;
            _currentWindowsShow = null;
        }

        private static Brush ConvertToBrush(object value)
        {
            var newvalue = value as Brush;
            if (newvalue == null)
            {
                throw new InvalidCastException("value must be Brush type");
            }
            return newvalue;
        }

        #endregion

        #region Implementation of IMessageSettingsService

        public void DefaultValues()
        {
            ResetToDefaultValues();
        }

        public IWindowsBoxSettingsService BorderColor(object valueColor)
        {
            if (!(valueColor is Color))
            {
                throw new InvalidCastException("value must be Color type");
            }
            _borderColor = (Color)valueColor;
            DefaultBorderBrush = new SolidColorBrush(_borderColor);
            return this;
        }

        public IWindowsBoxSettingsService ButtonBackgroundBrush(object valueBrush)
        {
            DefaultButtonBackgroundBrush = ConvertToBrush(valueBrush);
            return this;
        }

        public IWindowsBoxSettingsService ButtonForegroundBrush(object valueBrush)
        {
            DefaultButtonForegroundBrush = ConvertToBrush(valueBrush);
            return this;
        }

        public IWindowsBoxSettingsService ContentBackgroundBrush(object valueBrush)
        {
            DefaultContentBackgroundBrush = ConvertToBrush(valueBrush);
            return this;
        }

        public IWindowsBoxSettingsService ContentForegroundBrush(object valueBrush)
        {
            DefaultContentForegroundBrush = ConvertToBrush(valueBrush);
            return this;
        }

        public IWindowsBoxSettingsService TitleBackgroundBrush(object valueBrush)
        {
            DefaultTitleBackgroundBrush = ConvertToBrush(valueBrush);
            return this;
        }

        public IWindowsBoxSettingsService TitleForegroundBrush(object valueBrush)
        {
            DefaultTitleForegroundBrush = ConvertToBrush(valueBrush);
            return this;
        }

        public IWindowsBoxSettingsService OverlayColor(object valueColor)
        {
            if (!(valueColor is Color))
            {
                throw new InvalidCastException("value must be Color type");
            }
            _overlayColor = (Color)valueColor;
            DefaultOverlayBrush = new SolidColorBrush(_overlayColor) { Opacity = _overlayOpacity };
            return this;
        }

        public IWindowsBoxSettingsService OverlayOpacity(double value)
        {
            _overlayOpacity = value;
            DefaultOverlayBrush = new SolidColorBrush(_overlayColor) { Opacity = _overlayOpacity };
            return this;
        }

        public IWindowsBoxSettingsService Border(double value)
        {
            _border = value;
            DefaultThicknessTitle = new Thickness(value, value, value, value);
            DefaultThicknessMessage = new Thickness(value, 0, value, 0);
            DefaultThicknessButtons = new Thickness(value, 0, value, value);
            return this;
        }

        public IWindowsBoxSettingsService CornerRadius(double value)
        {
            _cornerRadius = value;
            DefaultCornerRadiusTop = new CornerRadius(value, value, 0, 0);
            DefaultCornerRadiusBottom = new CornerRadius(0, 0, value, value);
            return this;
        }

        public IWindowsBoxSettingsService ErrorBackgroundBrush(object valueBrush)
        {
            DefaultErrorBackgroundBrush = ConvertToBrush(valueBrush);
            return this;
        }

        public IWindowsBoxSettingsService ErrorForegroundBrush(object valueBrush)
        {
            DefaultErrorForegroundBrush = ConvertToBrush(valueBrush);
            return this;
        }

        public IWindowsBoxSettingsService WarningBackgroundBrush(object valueBrush)
        {
            DefaultWarningBackgroundBrush = ConvertToBrush(valueBrush);
            return this;
        }

        public IWindowsBoxSettingsService WarningForegroundBrush(object valueBrush)
        {
            DefaultWarningForegroundBrush = ConvertToBrush(valueBrush);
            return this;
        }

        public IWindowsBoxSettingsService InformationBackgroundBrush(object valueBrush)
        {
            DefaultInformationBackgroundBrush = ConvertToBrush(valueBrush);
            return this;
        }

        public IWindowsBoxSettingsService InformationForegroundBrush(object valueBrush)
        {
            DefaultInformationForegroundBrush = ConvertToBrush(valueBrush);
            return this;
        }

        public IWindowsBoxSettingsService QuestionBackgroundBrush(object valueBrush)
        {
            DefaultQuestionBackgroundBrush = ConvertToBrush(valueBrush);
            return this;
        }

        public IWindowsBoxSettingsService QuestionForegroundBrush(object valueBrush)
        {
            DefaultQuestionForegroundBrush = ConvertToBrush(valueBrush);
            return this;
        }

        #endregion

        #region Implementation of IMessageService

        public IWindowsBoxService Title(string value)
        {
            EnsureState();
            _windowsBoxBaseRef.Title = value;
            return this;
        }

        public IWindowsBoxService ButtonType(WindowsBoxButtonType value)
        {
            EnsureState();
            _windowsBoxBaseRef.ButtonType = value;
            return this;
        }

        public IWindowsBoxService Icon(WindowsBoxIconType value)
        {
            EnsureState();
            _windowsBoxBaseRef.ShowIconType = value;
            _windowsBoxBaseRef.ExternalIcon = null;
            return this;
        }

        public IWindowsBoxService Icon(object value)
        {
            EnsureState();
            var imgsrc = value as ImageSource;
            if (imgsrc == null)
            {
                throw new InvalidOperationException("value not type Image Source.");
            }
            _windowsBoxBaseRef.ShowIconType = WindowsBoxIconType.ExternalSource;
            _windowsBoxBaseRef.ExternalIcon = imgsrc;
            return this;
        }

        public IWindowsBoxService AddButton(string title, int value)
        {
            EnsureState();
            _windowsBoxBaseRef.ButtonType = WindowsBoxButtonType.Custom;
            _windowsBoxBaseRef.Buttons.Add(new WindowsBoxButton(title, value));
            return this;
        }

        public IWindowsBoxService AfterClosed(Action<WindowsBoxResultEventArgs> value)
        {
            EnsureState();
            _windowsBoxBaseRef.ActionClosed = value;
            return this;
        }

        public IWindowsBoxService AfterOpen(Action<EventArgs> value)
        {
            EnsureState();
            _windowsBoxBaseRef.ActionOpen = value;
            return this;
        }

        public void Show(object value)
        {
            EnsureState();
            if (value == null)
            {
                throw new InvalidOperationException("Message is null.");
            }
            if (value as FrameworkElement == null)
            {
                throw new InvalidOperationException("Message not is type Framework Element.");
            }
            InternalShow(new[] { value });
        }

        public void Show(string value)
        {
            EnsureState();
            if (value == null)
            {
                throw new InvalidOperationException("Message is null.");
            }
            if (_windowsBoxBaseRef == null)
            {
                throw new InvalidOperationException("Message Service not created.");
            }
            InternalShow(new[] { value });
        }

        public void CloseBox()
        {
            Close();
        }

        public void CloseBox(int value)
        {
            Close(value);
        }

        public void CloseBox(WindowsBoxButtonResult buttonResult)
        {
            Close(buttonResult);
        }

        #endregion

        #region Implementation of IMessageBoxService

        public IWindowsBoxMessage MessageBox(string title, WindowsBoxMessageType type)
        {
            return MessageBox(title, type, null, null);
        }

        public IWindowsBoxMessage MessageBox(string title, WindowsBoxMessageType type, Action<WindowsBoxResultEventArgs> whenClosed)
        {
            return MessageBox(title, type, whenClosed, null);
        }

        public IWindowsBoxMessage MessageBox(string title, WindowsBoxMessageType type, Action<WindowsBoxResultEventArgs> whenClosed, Action<EventArgs> whenOpen)
        {
            switch (type)
            {
                case WindowsBoxMessageType.Error:
                    return (IWindowsBoxMessage)Create(WindowsBoxTypeMessage.ErrorType)
                                                    .Title(title)
                                                    .Icon(WindowsBoxIconType.Error)
                                                    .ButtonType(WindowsBoxButtonType.Ok)
                                                    .AfterClosed(whenClosed)
                                                    .AfterOpen(whenOpen);
                case WindowsBoxMessageType.Warning:
                    return (IWindowsBoxMessage)Create(WindowsBoxTypeMessage.WarningType)
                                                    .Title(title)
                                                    .Icon(WindowsBoxIconType.Warning)
                                                    .ButtonType(WindowsBoxButtonType.OkCancel)
                                                    .AfterClosed(whenClosed)
                                                    .AfterOpen(whenOpen);
                case WindowsBoxMessageType.Information:
                    return (IWindowsBoxMessage)Create(WindowsBoxTypeMessage.InformationType)
                                                    .Title(title)
                                                    .Icon(WindowsBoxIconType.Information)
                                                    .ButtonType(WindowsBoxButtonType.Ok)
                                                    .AfterClosed(whenClosed)
                                                    .AfterOpen(whenOpen);
                case WindowsBoxMessageType.Question:
                    return (IWindowsBoxMessage)Create(WindowsBoxTypeMessage.QuestionType)
                                                    .Title(title)
                                                    .Icon(WindowsBoxIconType.Question)
                                                    .ButtonType(WindowsBoxButtonType.YesNo)
                                                    .AfterClosed(whenClosed)
                                                    .AfterOpen(whenOpen);
            }
            throw new InvalidOperationException("message type not implemented.");
        }

        #endregion

        #region Implementation of IMessageDateTimePickerService

        public IWindowsBoxDatePicker DatePicker(string title, Action<WindowsBoxResultEventArgs> whenClosed)
        {
            return DatePicker(title, whenClosed, null);
        }
        public IWindowsBoxDatePicker DatePicker(string title, Action<WindowsBoxResultEventArgs> whenClosed, Action<EventArgs> whenOpen)
        {
            return (IWindowsBoxDatePicker)Create(WindowsBoxTypeMessage.DatePicker)
                                            .Title(title)
                                            .Icon(WindowsBoxIconType.None)
                                            .ButtonType(WindowsBoxButtonType.OkCancel)
                                            .AfterClosed(whenClosed)
                                            .AfterOpen(whenOpen);
        }


        public IWindowsBoxTimePicker TimePicker(string title, Action<WindowsBoxResultEventArgs> whenClosed)
        {
            return TimePicker(title, whenClosed, null);
        }

        public IWindowsBoxTimePicker TimePicker(string title, Action<WindowsBoxResultEventArgs> whenClosed, Action<EventArgs> whenOpen)
        {
            return (IWindowsBoxTimePicker)Create(WindowsBoxTypeMessage.TimePicker)
                                            .Title(title)
                                            .Icon(WindowsBoxIconType.None)
                                            .ButtonType(WindowsBoxButtonType.OkCancel)
                                            .AfterClosed(whenClosed)
                                            .AfterOpen(whenOpen);
        }

        public void Show(DateTime? initialValue)
        {
            Show(initialValue, WindowsBoxDatePickerShowPart.AllParts);
        }
        public void Show(DateTime? initialValue, WindowsBoxDatePickerShowPart selectors)
        {
            EnsureState();
            InternalShow(new[] { initialValue, (object)selectors });
        }

        #endregion

    }
}
